<template>
  <div>
    <h1>App</h1>
  </div>
</template>

<script>
import {
  isProxy,
  isRef,
  reactive,
  readonly,
  ref,
  shallowReactive,
  toRef,
  toRefs,
  unref,
  shallowReadonly,
  computed,
  isReadonly,
  toValue,
} from 'vue'

export default {
  setup() {
    const count = ref(1)
    const state = reactive({ name: '张三' })
    console.log(isRef(count)) // true
    console.log(isRef(10)) // false
    console.log(isRef(state)) // false

    console.log(unref(10)) // 10
    console.log(unref(count)) // 1
    console.log(unref(state)) // Proxy

    // 将对象中某个属性的值转换成 ref 数据返回。
    const name = toRef({ name: '张三' }, 'name')
    console.log(name) // Ref { value: '张三' }

    const name1 = toRef(state, 'name')
    console.log(name1) // Ref { value: '张三' }
    name1.value = '李四'
    console.log('state.name', state.name) // 李四

    // toRefs() 将对象中所有属性的值都转换成 ref 数据，然后返回一个普通对象
    //    可以用在处理 Proxy 数据解构，会丢失响应式的问题
    const p1 = reactive({ a: 1, b: 2, c: 3 })
    const obj = toRefs(p1)
    console.log(obj) // { a: Ref {value: 1}, b: Ref {value: 2}, c: Ref {value: 3} }

    // 直接对 p1 这个 reactive 数据做解构
    let { a } = p1
    console.log(a) // 1
    a = 5
    console.log(p1.a) // 1

    // const { a, b, c } = obj
    // a.value = 5
    // console.log(p1.a) // 5

    // isProxy() 用于判断传递的数据是否有 reactive readonly shallowReactive shallowReadonly 所创建的数据
    console.log(isProxy(p1)) // true
    const p2 = readonly({})
    console.log(isProxy(p2)) // true
    console.log(isProxy(shallowReactive({}))) // true
    console.log(isProxy(shallowReadonly({}))) // true
    console.log(isProxy(ref(1)))

    const r1 = ref(10)
    const r1Plus = computed(() => r1.value * 2)
    console.log(isReadonly(r1Plus)) // true

    function fn1(id) {
      // console.log('id', id)
      // axios.get('/?id=' + id)
      // id 可能是一个数字，也可能是一个 ref 数字，为了更好兼容这种情况，可以使用 unref 对 id 参数做解包
      console.log('id', unref(id))
    }

    fn1(10)
    fn1(ref(20))

    function fn2(id) {
      // id 可能是一个数字，也可能是一个 ref 数字，还有可能是一个 () => 数字，可以使用 toValue 来处理
      console.log(toValue(id))
    }

    fn2(10)
    fn2(ref(20))
    fn2(() => 30)
  },
}
</script>
